from flask import  Flask
from flask import request
from flask import jsonify

from flask_cors import cross_origin

from util import utils
from Inferance import paddleInferance as pi
from common import Error
import json
app = Flask(__name__)

'''
request json
{
    'task': 'Seg' | 'CD' | 'PDet' | 'Det',  请求任务： 目标提取 | 变化检测 | 地物分类 | 目标检测
    'img_a': '',                            待处理的图片base64编码
    'img_b': ''                             仅变化检测使用,后时序图 
}

responce
{
    'code':     状态码
    'prod':     预测图
    'label':    标签(未处理，用于存入数据库中)
    'time':     处理时长
    'err':      错误信息
}
'''
@app.route('/hello', methods=['GET'])
@cross_origin()
def hello():
    print("index")
    return "index"

#@app.route('/api/infer', methods=['POST'])
#@cross_origin()
def Infer():
    data = request.get_data()
    #接受前端发送来的base64编码的图片
    json_data = json.loads(data.decode("utf-8"))
    task = json_data.get("task")
    print("收到推理请求:",task)
    if task==None:
        print(Error.MISS_PARAM.tostring())
        return jsonify({'code':Error.MISS_PARAM.code, 'prod':None, 'label':None, "err":Error.MISS_PARAM.tostring()})
    if task=="CD":
        #处理变换检测任务
        img_a = json_data.get("img_a").split(",")[1]
        img_b = json_data.get("img_b").split(",")[1]
        #print(len(img_a))
        if img_a==None or img_b==None:
            return jsonify({'code':Error.MISS_PARAM.code, 'prod':None, 'label':None, "err":Error.MISS_PARAM.tostring()})
        #对base64进行解码，转为opencv读取格式
        img_a = utils.base64_to_image(img_a)
        img_b = utils.base64_to_image(img_b)
        if not img_a.shape==img_b.shape:
            return jsonify({'code' : Error.A_B_IMG_SIZE_NOT_EQUAL.code, 'prod' : None, 'label':None, 'err' : Error.A_B_IMG_SIZE_NOT_EQUAL.tostring()})
        #print(img_a.shape,img_b.shape)
        #开始推理
        prod, label, time = pi.CDInferancer.inferOne(img_a,img_b)
        #将推理结果编码成base64字符串
        prod = utils.image_to_base64(prod)
        label = utils.image_to_base64(label)
        #print(prod)
        #返回前端 code:状态码 200表成功 pord:推理结果图的base64编码
        return jsonify({'code' : 200, 'prod' : prod, 'label':label, 'time':time, 'err' : None})
    elif task=="Seg":
        #处理目标提取任务
        img_a = json_data.get("img_a").split(",")[1]
        if img_a == None:
            return jsonify({'code':Error.MISS_PARAM.code, 'prod':None, 'label':None, "err":Error.MISS_PARAM.tostring()})
        img_a = utils.base64_to_image(img_a)
        prod, label, time = pi.SegInferancer.inferOne(img_a)
        prod = utils.image_to_base64(prod)
        label = utils.image_to_base64(label)
        #print(type(label))
        return jsonify({'code' : 200, 'prod' : prod, 'label':label, 'time':time, 'err' : None})
    elif task == "PDet":
        #处理地物分类任务
        img_a = json_data.get("img_a").split(",")[1]
        if img_a == None:
            return jsonify({'code':Error.MISS_PARAM.code, 'prod':None, 'label':None, "err":Error.MISS_PARAM.tostring()})
        img_a = utils.base64_to_image(img_a)
        prod, label, time = pi.PDetInferancer.inferOne(img_a)
        prod = utils.image_to_base64(prod)
        label = utils.image_to_base64(label)
        return jsonify({'code' : 200, 'prod' : prod, 'label':label, 'time':time, 'err' : None})
    elif task == "Det":
        #处理目标检测任务
        img_a = json_data.get("img_a").split(",")[1]
        if img_a == None:
            return jsonify({'code':Error.MISS_PARAM.code, 'prod':None, 'label':None, "err":Error.MISS_PARAM.tostring()})
        img_a = utils.base64_to_image(img_a)
        prod, label, time = pi.DetInferancer.inferOne(img_a)
        print(type(str(label)))
        prod = utils.image_to_base64(prod)
        return jsonify({'code' : 200, 'prod' : prod, 'label':str(label), 'time':time, 'err' : None})
    else:
        #未定义任务，无效请求
        return jsonify({'code' : Error.INVALID_REQUEST.code , 'prod' : None, 'label':None, 'err' : Error.INVALID_REQUEST.tostring()})


'''
request json
{
    'task':     'Seg' | 'CD' | 'PDet' | 'Det',  请求任务： 目标提取 | 变化检测 | 地物分类 | 目标检测
    'postfunc': '',                             后处理函数
    'label':    '',                             推理标签
    'image':    '',                             原图
    'param':    '',                             后处理请求参数 
}

responce
{
    'code':     状态码
    'prod':     预测图
    'time':     处理时长
    'err':      错误信息
}
客户端主动调用或当模型预测结果已经缓存在数据库中时调用
'''

@app.route('/api/postprocess', methods=['POST'])
@cross_origin()
def Postprocess():
    data = request.get_data()
    #接受前端发送来的base64编码的图片
    json_data = json.loads(data.decode("utf-8"))
    task = json_data.get("task")
    postfunc = json_data.get("postfunc")
    image = json_data.get("image").split(",")[1]
    param = json_data.get("param")
    print("后处理请求参数:",param)
    print("原图数据",image[:5])
    print("收到后处理请求:",task)
    image = utils.base64_to_image(image)
    if task==None or postfunc==None:
        print(Error.MISS_PARAM.tostring())
        return jsonify({'code':Error.MISS_PARAM.code, 'prod':None, "err":Error.MISS_PARAM.tostring()})
    label = json_data.get("label")
    if label == None:
        return jsonify({'code':Error.MISS_PARAM.code, 'prod':None, "err":Error.MISS_PARAM.tostring()})
    if task=="CD":
        label = utils.base64_to_image(label)
        if postfunc=="default":
            #调用默认后处理函数
            prod, time = utils.CDpostProcess(label, image)
            prod = utils.image_to_base64(prod)
            return jsonify({'code' : 200, 'prod' : prod, 'time':time, 'err' : None})
        else:
            return jsonify({'code' : Error.INVALID_REQUEST.code , 'prod' : None, 'err' : Error.INVALID_REQUEST.tostring()})
    elif task=="PDet":
        label = utils.base64_to_image(label)
        if postfunc=="default":
            #调用默认后处理函数
            prod, time = utils.PDetProcess(label, image)
            prod = utils.image_to_base64(prod)
            return jsonify({'code' : 200, 'prod' : prod, 'time':time, 'err' : None})
        elif postfunc=="onlyshowOne":
            #仅显示一类
            prod, time = utils.PDetProcess(label, image, param)
            prod = utils.image_to_base64(prod)
            return jsonify({'code' : 200, 'prod' : prod, 'time':time, 'err' : None})
        else:
            return jsonify({'code' : Error.INVALID_REQUEST.code , 'prod' : None, 'err' : Error.INVALID_REQUEST.tostring()})
    elif task=="Seg":
        label = utils.base64_to_image(label)
        if postfunc=="default":
            #调用默认后处理函数
            prod, time = utils.SegpostProcess(label, image)
            # prod = utils.CDpostProcess(label, image)
            prod = utils.image_to_base64(prod)
            return jsonify({'code' : 200, 'prod' : prod, 'time':time, 'err' : None})
        else:
            return jsonify({'code' : Error.INVALID_REQUEST.code , 'prod' : None, 'err' : Error.INVALID_REQUEST.tostring()})
    elif task=="Det":
        #print(label)
        label = utils.Str_to_Detlabel(label)
        if postfunc=="default":
            #调用默认后处理函数
            prod, time = utils.DetpostProcess(label, image)
            prod = utils.image_to_base64(prod)
            return jsonify({'code' : 200, 'prod' : prod, 'time':time, 'err' : None})
        elif postfunc=="changethreshold":
            #调整置信度阈值
            prod, time = utils.DetpostProcess(label, image, param)
            prod = utils.image_to_base64(prod)
            return jsonify({'code' : 200, 'prod' : prod, 'time':time, 'err' : None})
        else:
            return jsonify({'code' : Error.INVALID_REQUEST.code , 'prod' : None, 'err' : Error.INVALID_REQUEST.tostring()})
    else:
        return jsonify({'code' : Error.INVALID_REQUEST.code , 'prod' : None, 'err' : Error.INVALID_REQUEST.tostring()})
